package gui.standard.form;

import gui.main.form.MainFrame;

import java.awt.Dimension;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.tablemodel.AbstractTableModel;
import net.miginfocom.swing.MigLayout;
import actions.standard.form.AddAction;
import actions.standard.form.CommitAction;
import actions.standard.form.DeleteAction;
import actions.standard.form.FirstAction;
import actions.standard.form.HelpAction;
import actions.standard.form.LastAction;
import actions.standard.form.NextAction;
import actions.standard.form.NextFormAction;
import actions.standard.form.PickupAction;
import actions.standard.form.PreviousAction;
import actions.standard.form.RefreshAction;
import actions.standard.form.RollbackAction;
import actions.standard.form.SearchAction;

public abstract class StandardForm extends JDialog {

	private static final long serialVersionUID = 1L;

	public static final int MODE_EDIT = 1;
	public static final int MODE_ADD = 2;
	public static final int MODE_SEARCH = 3;
	protected int mode = MODE_ADD;

	protected JToolBar toolBar;
	protected JButton btnAdd, btnCommit, btnDelete, btnFirst, btnLast, btnHelp,
			btnNext, btnNextForm, btnPickup, btnRefresh, btnRollback,
			btnSearch, btnPrevious;
	protected JTable tblGrid;
	protected JPanel buttonsPanel;

	protected StandardForm pickupForm;

	protected boolean useDatabase = true; // if set to false the application
											// will not try to connect to the
											// database
	
	protected ArrayList<StandardForm> children = new ArrayList<StandardForm>();
	
	protected AbstractTableModel tableModel;

	public StandardForm() {

	}
	
	public void init(){
		
		setLayout(new MigLayout("fill"));

		setSize(new Dimension(800, 600));
		setLocationRelativeTo(MainFrame.getInstance());
		setModal(true);
		
		tblGrid = new JTable();
		buttonsPanel = new JPanel();

		toolBar = new JToolBar();
		btnSearch = new JButton(new SearchAction(this));
		toolBar.add(btnSearch);

		btnRefresh = new JButton(new RefreshAction());
		toolBar.add(btnRefresh);

		btnPickup = new JButton(new PickupAction(this));
		toolBar.add(btnPickup);

		btnHelp = new JButton(new HelpAction());
		toolBar.add(btnHelp);

		toolBar.addSeparator();

		btnFirst = new JButton(new FirstAction(this));
		toolBar.add(btnFirst);

		btnPrevious = new JButton(new PreviousAction(this));
		toolBar.add(btnPrevious);

		btnNext = new JButton(new NextAction(this));
		toolBar.add(btnNext);

		btnLast = new JButton(new LastAction(this));
		toolBar.add(btnLast);

		toolBar.addSeparator();

		btnAdd = new JButton(new AddAction(this));
		toolBar.add(btnAdd);

		btnDelete = new JButton(new DeleteAction(this));
		toolBar.add(btnDelete);

		toolBar.addSeparator();

		btnNextForm = new JButton(new NextFormAction(this));
		toolBar.add(btnNextForm);

		add(toolBar, "dock north");

		tblGrid.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tblGrid.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {

					@Override
					public void valueChanged(ListSelectionEvent arg0) {
						// TODO Auto-generated method stub
						if (arg0.getValueIsAdjusting())
							return;
						sync();

					}
				});

		tblGrid.setRowSelectionAllowed(true);
		tblGrid.setColumnSelectionAllowed(false);

		JScrollPane scrollPane = new JScrollPane(tblGrid);
		add(scrollPane, "grow, wrap");

		btnCommit = new JButton(new CommitAction(this));
		btnRollback = new JButton(new RollbackAction(this));

		buttonsPanel.setLayout(new MigLayout("wrap"));
		buttonsPanel.add(btnCommit);
		buttonsPanel.add(btnRollback);
		
	}

	// ////////////////////////POZICIONIRANJE///////////////////////////////////

	public void goLast() {
		int rowCount = tblGrid.getModel().getRowCount();
		if (rowCount > 0)
			tblGrid.setRowSelectionInterval(rowCount - 1, rowCount - 1);

		setMode(StandardForm.MODE_EDIT);
	}

	public void goFirst() {
		int rowCount = tblGrid.getModel().getRowCount();
		if (rowCount > 0)
			tblGrid.setRowSelectionInterval(0, 0);

		setMode(StandardForm.MODE_EDIT);
	}

	public void goNext() {
		int rowCount = tblGrid.getModel().getRowCount();
		int index = tblGrid.getSelectedRow();
		if (rowCount > 0) {
			if (index < rowCount - 1) {
				tblGrid.setRowSelectionInterval(index + 1, index + 1);
			} else {
				tblGrid.setRowSelectionInterval(0, 0);
			}
		}

		setMode(StandardForm.MODE_EDIT);

	}

	public void goPrevious() {
		int rowCount = tblGrid.getModel().getRowCount();
		int index = tblGrid.getSelectedRow();
		if (rowCount > 0) {
			if (index > 0) {
				tblGrid.setRowSelectionInterval(index - 1, index - 1);
			} else {
				tblGrid.setRowSelectionInterval(rowCount - 1, rowCount - 1);
			}
		}

		setMode(StandardForm.MODE_EDIT);

	}

	public abstract void searchRow();

	// /////////////////////EDIT TABLE////////////////////////////////////

	public abstract void addRow();

	public abstract void editRow();

	public void removeRow() {
		int index = tblGrid.getSelectedRow();
		if (index == -1) // Ako nema selektovanog reda (tabela prazna)
			return; // izlazak
		// kada obrisemo tekuci red, selektovacemo sledeci (newindex):

		int dialogResult = JOptionPane.showConfirmDialog(this,
				"Jeste li sigurni da zelite obrisati kolonu?");
		if (dialogResult == JOptionPane.YES_OPTION) {
			int newIndex = index;
			// sem ako se obrise poslednji red, tada selektujemo prethodni
			if (index == tblGrid.getModel().getRowCount() - 1)
				newIndex--;
			try {
				AbstractTableModel dtm = (AbstractTableModel) tblGrid
						.getModel();
				dtm.deleteRow(index);
				if (tblGrid.getModel().getRowCount() > 0)
					tblGrid.setRowSelectionInterval(newIndex, newIndex);
			} catch (SQLException ex) {
				JOptionPane.showMessageDialog(this, ex.getMessage(), "Greska",
						JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	// /////////////////////SUPPORT///////////////////////////////////////

	public void setMode(int mode) {
		this.mode = mode;
	}

	public void commitChange() {
		switch (mode) {
		case MODE_ADD:
			addRow();
			break;
		case MODE_EDIT:
			editRow();
			break;
		case MODE_SEARCH:
			searchRow();
		}
	}

	public StandardForm getPickupForm() {
		return this.pickupForm;
	}

	public void setPickupForm(StandardForm pickupForm) {
		this.pickupForm = pickupForm;
	}

	public abstract void sync();
	
	public abstract void getZoomedCol(String[] keys, StandardForm form);
	
	public abstract String[] getSelectedRowKeys();
	
	public abstract String[] getSelectedRowNextKeys(int index);
	
	public ArrayList<StandardForm> getChildren(){
		return this.children;
	}
	
	public AbstractTableModel getTableModel(){
		return this.tableModel;
	}
	
	public void open(){
		if (useDatabase) {
			try {
				tableModel.open();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public String toString(){
		return getTitle();
	}
}
